package com.datasecops.scannerservices.service;

import com.datasecops.scannerservices.config.ConfigFilePath;
import com.datasecops.scannerservices.db.Redis;
import com.datasecops.scannerservices.entity.CommonParam;
import com.datasecops.scannerservices.enumerate.EngineStatus;
import com.datasecops.scannerservices.util.ByteStreamHelper;
import lombok.extern.slf4j.Slf4j;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.List;

/**
 * 扫描数据处理类
 * @author: SunLingzhi
 * @time: 2022/8/29 10:59
 */
@Service
@Slf4j
public class ScanDataProcessServers {

    @Resource
    private ScannerEngineServer engineServer;

    Element dbDataElem = DocumentHelper.createElement("DBData");
    Element colData;
    String path;


    /**
     * 数据落盘
     *
     * @param
     * @param commonParam
     * @param jobId
     * @param jobName
     * @param scannerID
     * @param linage
     * @return
     * @Description
     * @author SunLingzhi
     * @time 2022/8/18 17:43
     */
    public boolean tradingData(CommonParam param, CommonParam commonParam, List<String> list, int col, Boolean newLine, String filename, String nameSuffix, String jobId, String jobName, String scannerID, String linage) {

        //基础path
        StringBuilder basicPath = new StringBuilder(ConfigFilePath.getScannerDirPath() + File.separator + param.getJobId() + File.separator + param.getUUId());
        //暂存目录
        StringBuilder filePath = new StringBuilder(basicPath);

        filePath.append(File.separator + "dbdata_" + param.getDbName() + File.separator + param.getTableName() + "_" + col);

        File file = new File(filePath.toString());
        if (!file.exists()){
            file.mkdirs();
        }
//        LinkedList<String> list = new LinkedList<>();
//        LinkedList<Integer> lists = new LinkedList<>();
        Redis redis = new Redis();
        OutputStreamWriter out = null;

//        StringBuilder path1 = new StringBuilder();
//        path1.append(basicPath);

//        StringBuilder path2 = new StringBuilder();
//        path2.append(basicPath);


        filePath.append(File.separator).append(filename);
        //filePath.append(File.separator).append("key_data_index_");


        StringBuilder tempPath;

        int colIndex = 0;
        //>>>>>>>>>>>扫描数据落盘
//        sourceData.forEach((key, value) -> {
//            //list.add(key);
//            list.add(String.valueOf(value));
////            Integer souls = redis.souls(String.valueOf(value));
////            lists.add(souls);
//        });

        //sourceData.forEach((key, value) -> list.add(key));

           /* for (Map.Entry<String, LinkedList<String>> entry : sourceData.entrySet()) {
                colIndex++;
               // list = entry.getValue();
                list.add(entry.getKey());//第一行，为title

            }*/
                //第一行，为title
                //落盘
                tempPath = new StringBuilder(filePath);
                tempPath.append(colIndex).append(nameSuffix);
                colIndex++;
                //tempPaths.append(colIndex).append(".txt");

                try {
                    out = new OutputStreamWriter(new FileOutputStream(tempPath.toString()), StandardCharsets.UTF_8);
                    BufferedWriter bw = new BufferedWriter(out);

//                    BufferedWriter bws = new BufferedWriter(out);
//                    for (Integer integer : lists) {
//                        bws.write(integer + "|");
//                       // bws.newLine();
//                    }
//                    bws.flush();
//                    bws.close();

                    for (String s : list) {
                        bw.write(s);
                        if (newLine == true){
                            bw.newLine();
                        }
                    }
                    bw.flush();
                    bw.close();
                } catch (Exception e) {
                    log.error("Failed Method tradingData error: " + e.getMessage());
                    return false;
                }finally{
                    if(out != null){
                        try {
                            out.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }


        //>>>>>>>>>>>说明XML文件落盘
        Element rootElem = DocumentHelper.createElement("TaskInfo");
        rootElem.addAttribute("Type","DB");
        //DB_INFO
        Element dbInfoElem = DocumentHelper.createElement("DBInfo");
        dbInfoElem.addAttribute("dbtype",param.getTypeEnum().name().replace("_","-"));//数据类型
        dbInfoElem.addAttribute("serverip",param.getIp());//数据库地址
        dbInfoElem.addAttribute("serverPort",param.getPort()+"");//端口
        dbInfoElem.addAttribute("dbname",param.getDbName());//数据库名称
        dbInfoElem.addAttribute("tablename",param.getTableName());//表名称
        dbInfoElem.addAttribute("tablerowcount",linage);//表总行数
        dbInfoElem.addAttribute("tableindex",col+"");//第几批次
        dbInfoElem.addAttribute("resguid",param.getUUId());//uuId
        dbInfoElem.addAttribute("db_relation_type","keyvalue");//非关系型数据库
        rootElem.add(dbInfoElem);

        //TaskkBaseInfo
        Element taskkBaseInfo = DocumentHelper.createElement("TaskBaseInfo");
        taskkBaseInfo.addAttribute("TaskID",jobId);
        taskkBaseInfo.addAttribute("TaskName",jobName);
        taskkBaseInfo.addAttribute("ScannerID",scannerID);
        rootElem.add(taskkBaseInfo);

        //TaskkProgressInfo
        Element taskkProgressInfo = DocumentHelper.createElement("TaskProgressInfo");
        taskkProgressInfo.addAttribute("sum_row_count","0");
        taskkProgressInfo.addAttribute("cur_row_pos","0");
        taskkProgressInfo.addAttribute("cur_row_count","0");
        rootElem.add(taskkProgressInfo);


        //DB_Policy
        Element dbPolicy = DocumentHelper.createElement("DBPolicy");
        dbPolicy.addAttribute("PolicyPath",commonParam.getPolicyPath());
        dbPolicy.addAttribute("FingerPath",commonParam.getFingerPath());
        dbPolicy.addAttribute("DictPath",commonParam.getDictPath());
        dbPolicy.addAttribute("MchClusterPath",commonParam.getMchClusterPath());
        rootElem.add(dbPolicy);

        //DB_DATA
        if (colData == null){//这里判断是因为这是新的一轮了.
            dbDataElem = DocumentHelper.createElement("DBData");
        }

//        Element colData;
//        String path;

        for (int i = 1; i <= colIndex; i++) {
            colData = DocumentHelper.createElement("ColData");
            colData.addAttribute("name","");
            path = filePath.toString() + i + nameSuffix;
            colData.addAttribute("Path",path);
            dbDataElem.add(colData);
            if (nameSuffix.equalsIgnoreCase(".dat")){
                return true;
            }
        }
        rootElem.add(dbDataElem);

        OutputStreamWriter xmlWriter = null;
        StringBuilder xmlPath = new StringBuilder(basicPath);
        xmlPath.append(File.separator).append("config_").append(param.getDbName()).append("_").append(param.getTableName()).append("_").append(col).append(".xml");
        try {
            String xmlStr = ByteStreamHelper.toXmlString(rootElem);
            byte[] bom = {-1, -2};
            FileOutputStream outputStream = new FileOutputStream(xmlPath.toString());
            outputStream.write(bom);

            xmlWriter = new OutputStreamWriter(outputStream, StandardCharsets.UTF_16LE);
            BufferedWriter bw = new BufferedWriter(xmlWriter);

            bw.write(xmlStr);
            bw.flush();
            bw.close();
        } catch (IOException e) {
            log.error("Failed Method Write xml error: " + e.getMessage());
        }finally {
            if (null != xmlWriter){
                try {
                    xmlWriter.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            dbDataElem = null;
             colData = null;
             path = null;
        }

        //调用引擎传输数据
        engineServer.callScannerEngine(param.getJobId(), "scanproxy", EngineStatus.DATA.getValue(),xmlPath.toString());
        return true;
    }
}
